package zl.applet.block;
import java.awt.Color;
import java.awt.Graphics;

import javax.swing.JPanel;

//方块所处面板类
public class Canvas extends JPanel
{
	private static final long serialVersionUID = 1L;
	private int rows,cols,boxWidth,boxHeight;		//面板的行。列。一个格子的宽。一个格子的高
	private Color backColor,frontColor;				//面板的背景色、及前景色
	private Box[][] boxes;							//格子二维数组
	private BlockGame game;							//面板所在的窗体

	//构造函数
	public Canvas(int rows,int cols,Color backColor,Color frontColor,BlockGame game)
	{
		this.rows = rows;
		this.cols = cols;
		this.backColor = backColor;
		this.frontColor = frontColor;
		this.game = game;
		this.boxes = new Box[this.rows][this.cols];
		for(int i = 0; i < this.boxes.length; i++)
		{
			//初始化整个面板的格子
			for(int j = 0; j < this.boxes[i].length; j++)
			{
				this.boxes[i][j] = new Box(false);
			}
		}
	}

	public void setRows(int rows)
	{
		this.rows = rows;
	}
	public int getRows()
	{
		return this.rows;
	}

	public void setCols(int cols)
	{
		this.cols = cols;
	}
	public int getCols()
	{
		return this.cols;
	}

	public int getBoxWidth()
	{
		return this.boxWidth;
	}
	public int getBoxHeight()
	{
		return this.boxHeight;
	}

	public void setBackColor(Color backColor)
	{
		this.backColor = backColor;
	}
	public Color getColor()
	{
		return this.backColor;
	}

	public void setFrontColor(Color frontColor)
	{
		this.frontColor = frontColor;
	}
	public Color getFrontColor()
	{
		return this.frontColor;
	}

	public Box getBox(int row,int col)
	{
		if(row >= this.rows || col >= this.cols ||
			row < 0 || col < 0)
			return null;
		return this.boxes[row][col];
	}

	//重写JPanel的paint方法。用来画格子的颜色
	public void paint(Graphics g)
	{
		super.paint(g);
		for(int i = 0; i < this.boxes.length; i++)
		{
			for(int j = 0; j < this.boxes[i].length; j++)
			{
				g.setColor(this.boxes[i][j].getIsColor() ? this.frontColor : this.backColor);
				g.fill3DRect(j*this.boxWidth,i*this.boxHeight,this.boxWidth,this.boxHeight,true);
			}
		}
	}
	
	//计算面板里面包含格子的宽、高
	public void fanning()
	{
		this.boxWidth = this.getSize().width / this.cols;
		this.boxHeight = this.getSize().height / this.rows;
	} 

	//移除面板上的已经堆满的一行
	public void removeFullLine()
	{
		//从最下面的一行开始检查
		for(int i = this.rows - 1; i >= 0; i--)
		{
			int j = 0;
			//循环判断一行是否堆满
			for(; j < this.cols; j++)
			{
				if(!this.boxes[i][j].getIsColor())	//如果一行有一列是无色的。就说明没堆满。则跳出此循环
					break;
			}
			if(j == this.cols)	//判断上面的代码是否正常循环完。正常循环完则代表一行已堆满
			{
				//这里是做了一个消除堆满行的特效。详细请看效果。
				Color[] c = {Color.BLACK,Color.BLUE,Color.CYAN,Color.DARK_GRAY,
					Color.GRAY,Color.GREEN,Color.LIGHT_GRAY,Color.MAGENTA,
					Color.ORANGE,Color.PINK,Color.RED,Color.WHITE,Color.YELLOW};
				Graphics g = this.getGraphics();
				for(int a = 0; a < c.length; a++)
				{
					g.setColor(c[a]);
					for(int b = 0; b < this.boxes[i].length; b++)
					{
						g.fill3DRect(b*this.boxWidth,i*this.boxHeight,this.boxWidth,this.boxHeight,true);
					}
					try
					{
						Thread.sleep(50);
					}
					catch (InterruptedException e)
					{
						e.printStackTrace();
					}
				}
				this.game.setScore(this.game.getScore() + BlockGame.INCREMENT);
				//移除堆满行
				this.removeLine(i++); 
			}
		}
	}
	
	//移除指定行（移除此行后。上面的行都要相继移下一行）
	public synchronized void removeLine(int row)
	{
		for(int i = row; i > 0; i--)
		{
		 	for(int j = 0; j < this.cols; j++)
			{
				if(i - 1 >= 0)
				{
					//把上面一行克隆岛该下面一行
					this.boxes[i][j] = (Box)this.boxes[i - 1][j].clone();
				}
			}
			//重绘
			this.repaint();
		}
	}

	//检测状态（检测是否已堆到到顶部）
	public boolean checkState()
	{
		for(int i = 0; i < this.boxes[0].length; i++)
		{
			if(this.boxes[0][i].getIsColor())
				return false;
		}
		return true;
	}
	
	//面板重置
	public void reset()
	{
		for(int i = 0; i < this.boxes.length; i++)
		{
			for(int j = 0; j < this.boxes[i].length; j++)
			{
				this.boxes[i][j].setIsColor(false);
			}
		}
		this.repaint();
	}
}